﻿
/*
Service: 适用于管理所有服务器端的Rest接口的静态对象
serviceList: 包含了Rest接口的地址，方法，名称
InitService: 该方法会为每一个serviceItem生成4个方法
example:
Item: { name: "GetCurrentUser", url: "/core/GetCurrentUser", method: "get" },
Method: 
异步调用
GetCurrentUser
同步调用
GetCurrentUser_Sync
异步调用，使用缓存
GetCurrentUser_Cache
同步调用，使用缓存
GetCurrentUser_CacheSync

memo: 带缓存的方法只有当Rest的Method是Get的时候才能发生
*/

define(function (require, exports, module) {
    var utility = require('ezdesk/utility/utility.js');
    
    var service;
    service = GetService();
    service.BuildReference = GetBuildReferenceMethod();
    module.exports = service;

    function GetService() {
        var Service = {};
        Service.Cache = {};
        Service.serviceList = [
        { name: "Login", url: "/Login/", method: "post" },

        { name: "OrganizationInfo", url: "/Core/OrganizationInfo", method: "get" },

        { name: "AllAppFunctions", url: "/Core/AllAppFunctions", method: "get" },
        { name: "AllAppFunctionTypes", url: "/Core/AllAppFunctionTypes", method: "get" },
        { name: "AppFunctionsByTypeName", url: "/Core/AppFunctionsByTypeName", method: "get" },

        { name: "AllAppFunctionCategories", url: "/Core/AllAppFunctionCategories", method: "get" },
        { name: "AppFunctionsByCategoryName", url: "/Core/AppFunctionsByCategoryName", method: "get" },
        
        { name: "AppFunctionShortcutIds", url: "/Core/AppFunctionShortcutIds", method: "get" },
        { name: "UpdateAppFunctionShortcutSequnce", url: "/Core/UpdateAppFunctionShortcutSequnce", method: "post" },

        { name: "XmlFeedsByCount", url: "/Core/XmlFeedsByCount", method: "get" },
        { name: "XmlFeedsBetweenDate", url: "/Core/XmlFeedsBetweenDate", method: "get" },
        { name: "AllXmlFeedsBetweenDate", url: "/Core/AllXmlFeedsBetweenDate", method: "get" },
        { name: "AllXmlFeedsByCount", url: "/Core/AllXmlFeedsByCount", method: "get" },
        { name: "AllJsonFeedsBetweenDate", url: "/Core/AllJsonFeedsBetweenDate", method: "get" },
        { name: "AllJsonFeedsByCount", url: "/Core/AllJsonFeedsByCount", method: "get" },
        { name: "SetUserStatus", url: "/Core/SetUserStatus", method: "post" },
        { name: "UserStatus", url: "/Core/UserStatus", method: "get" },
        { name: "UpdateFeedStatus", url: "/Core/UpdateFeedStatus", method: "post" },

        { name: "UserProfileById", url: "/Core/UserProfileById", method: "get" },
        { name: "SimpleUserById", url: "/Core/SimpleUserById", method: "get" },
        { name: "SimpleUserInfos", url: "/Core/SimpleUserInfos", method: "get" },
        { name: "DeptById", url: "/Core/DeptById", method: "get" },

        { name: "ClientBaseUrl", url: "/Core/ClientBaseUrl", method: "get" },

        { name: "CurrentUser", url: "/Core/CurrentUser", method: "get" },
        { name: "TestLogin", url: "/Core/TestLogin", method: "get" },

        { name: "GetFeeds", url: "/Feeds", method: "get" },

    ];


        Service.InitService = function () {
            function GetCacheKey(serviceItem, args) {
                var argStr = args ? utility.toJSON(args) : "";
                return serviceItem.name + argStr;
            }
            function GenerateSyncMethod(serviceItem) {
                return function (callback, args, message, beforeCallBack, afterCallBack) {
                    var returnResult;
                    var cacheKey = GetCacheKey(serviceItem, args);
                    utility.SyncMethod(serviceItem.url, serviceItem.method)(function (result) {
                        GetBuildReferenceMethod(result);
                        Service.Cache[cacheKey] = result;
                        returnResult = result;
                    }, args, beforeCallBack, afterCallBack);


                    if (callback && callback != null)
                        callback(returnResult);
                    return returnResult;
                }
            }
            function GenerateAsyncMethod(serviceItem) {
                return function (callback, args, beforeCallBack, afterCallBack) {
                    var cacheKey = GetCacheKey(serviceItem, args);
                    utility.AsyncMethod(serviceItem.url, serviceItem.method)(function (result) {
                        GetBuildReferenceMethod(result);
                        Service.Cache[cacheKey] = result;
                        callback(result);
                    }, args, beforeCallBack, afterCallBack);
                }
            }
            function GenerateCacheSyncMethod(serviceItem) {
                return function (callback, args, message, beforeCallBack, afterCallBack) {
                    var cacheKey = GetCacheKey(serviceItem, args);
                    if (!Service.Cache[cacheKey] || Service.Cache[cacheKey] == null) {
                        Service[serviceItem.name + "_Sync"](function (result) { }, args, message, beforeCallBack, afterCallBack);
                    }
                    if (callback && callback != null) callback(Service.Cache[cacheKey]);
                    return Service.Cache[cacheKey];
                }
            }
            function GenerateCacheMethod(serviceItem) {
                return function (callback, args, beforeCallBack, afterCallBack) {
                    var cacheKey = GetCacheKey(serviceItem, args);
                    if (!Service.Cache[cacheKey] || Service.Cache[cacheKey] == null) {
                        Service[serviceItem.name](function (result) {
                            callback(result);
                        }, args, beforeCallBack, afterCallBack);
                    }
                    else
                        callback(Service.Cache[cacheKey]);
                }
            }

            for (var i = 0; i < Service.serviceList.length; i++) {
                var item = Service.serviceList[i];
                Service[item.name + "_Sync"] = GenerateSyncMethod(item);
                Service[item.name] = GenerateAsyncMethod(item);
                if (item.method == "get") {
                    Service[item.name + "_CacheSync"] = GenerateCacheSyncMethod(item);
                    Service[item.name + "_Cache"] = GenerateCacheMethod(item);

                }
            }
        };

        Service.InitService();
        return Service;
    };

    function GetBuildReferenceMethod() {
        var dictionary = {};
        var buildReference = function () { };
        buildReference = function (obj) {
            if (typeof (obj) != 'object') return;

            if (obj['$id']) {
                dictionary[obj['$id']] = obj;
            }
            for (var p in obj) {
                if (typeof (obj[p]) == 'object' && obj[p] != null) {
                    if (obj[p]['$ref']) {
                        var refId = obj[p]['$ref'];
                        obj[p] = dictionary[refId];
                    }
                    else
                        buildReference(obj[p]);
                }
            }
            return obj;
        }
        return buildReference;
    }

});

